package com.example.demo.reptile;

import com.example.demo.entity.ChapterList;
import com.example.demo.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wan
 * @version 1.0.0
 * @Description 爬取小说
 * @createTime 2021年08月27日 15:11:53
 */
@Slf4j
public class CrawlNovel {

    final static String WEBURL = "https://www.janpn.com";
    final static String SEACHPARAM = "/search.php?q='";

    /**
     * 参数拼接
     *
     * @param search
     * @return
     */
    public static String urlSplice(String search) {
        return WEBURL + SEACHPARAM + search + "'";
    }

    /**
     * 1
     * -- 获取书链接、章节链接
     *
     * @param url1
     * @return
     */
    public static List<String> getNovelHtml(String url1) {
        List<String> list = new ArrayList<>();
        try {
            URL url = new URL(url1);
            URLConnection urlconn = url.openConnection();
            InputStream is = urlconn.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String buf = null;
            while (true) {
                buf = br.readLine();
                //之所以搞两个空校验，是因为页面可能存在空行的情况
                if (StringUtils.isBlank(buf)) {
                    buf = br.readLine();
                    if (StringUtils.isBlank(buf)) {
                        break;
                    }
                }
                list.add(buf);
            }
        } catch (Exception e) {
            log.error(">>>>>网页爬取异常:{}：", e.getMessage());
            throw new BaseException("网页爬取异常:" + e.getMessage());
        }
        return list;
    }

    /**
     * 2
     * 获取书的链接（每本书有独立的链接）
     *
     * @param list
     * @param search
     * @return
     */
    public static String getNovelPath2Html(List<String> list, String search) {
        String url = null;
        for (String t : list) {
            //查找该书的链接
            String sss = "<a title=\"" + search + "\"";
            if (t.contains(sss)) {
                url = getChapterUrl(t);
                url = WEBURL + url;
            }
        }
        return url;
    }

    /**
     * 3
     * 获取章节及链接
     *
     * @param list
     * @return key-第x章，value-章节对应链接
     */
    public static List<ChapterList> getChapterList2Html(List<String> list, String novelPath) {
        List<ChapterList> chapterUrlList = new ArrayList<>();
        boolean starter = false;
        for (String text : list) {
            //寻找小说目录
            if (text.contains("<ul ") && text.contains("chapterlist")) {
                starter = true;
                continue;
            }
            //true说明已经找到目录，开始读取
            if (starter) {
                if (text.contains("href")) {
                    String chapterName = getChapterName(text);
                    String chapterUrl = getChapterUrl(text);
                    //完整书籍路径+每章节链接 拼接 全路径
                    chapterUrlList.add(ChapterList.builder().chapterName(chapterName).chapterUrl(novelPath.concat(chapterUrl)).build());
                } else {
                    //目录都提取完成后，直接跳出循环
                    break;
                }
            }
        }
        return chapterUrlList;
    }

    /**
     * 4
     * 单章节
     * 根据小说章节链接获取内容
     *
     * @param chaperListNameUrl
     * @return
     */
    public static List<String> getNovelChapterListDetail(String chaperListNameUrl) {
        int pre = 0;
        int end = 0;
        List<String> htmls = getNovelHtml(chaperListNameUrl);
        t:
        for (int i = 0; i < htmls.size(); i++) {
            String s = htmls.get(i);
            if (s.contains("htmlContent")) {
                pre = i;
            }
            if (s.contains("</div") && pre != 0) {
                end = i + 1;
                break t;
            }
        }
        List<String> list = htmls.subList(pre, end);
        list = contextDeal(list);
        return list;
    }

    /**
     * 处理从html提取出来的内容
     *
     * @param list
     * @return
     */
    public static List<String> contextDeal(List<String> list) {
        StringBuilder string = new StringBuilder();
        list.forEach(string::append);
        String s = string.toString();
        s = s.replace("&nbsp;&nbsp;&nbsp;&nbsp;", "    ");
        s = s.replace("</div>", "");
        s = s.replace("<div class=\"panel-body\" id=\"htmlContent\"> ", "");
        String[] split = s.split("<br />");
        //资源不浪费，清空再用
        list.removeAll(list);
        for (int i = 0; i < split.length; i++) {
            if (StringUtils.isNotBlank(split[i])) {
                list.add(split[i]);
            }
        }
        return list;
    }

    /**
     * 获取章节名字
     *
     * @param t
     * @return
     */
    public static String getChapterName(String t) {
        String key = null;
        String[] split = t.split("\">");
        for (int s = 0; s < split.length; s++) {
            if (split[s].contains("href")) {
                key = split[s + 1];
                String[] split1 = key.split("</a");
                for (int i = 0; i < split1.length; i++) {
                    key = split1[i];
                    return key;
                }
            }
        }
        return key;
    }

    /**
     * 获取章节对应链接
     *
     * @param t
     * @return
     */
    public static String getChapterUrl(String t) {
        if (t.contains("href")) {
            String[] split = t.split("\"");
            for (int i = 0; i < split.length; i++) {
                if (split[i].contains("href")) {
                    return split[i + 1];
                }
            }
        }
        return null;
    }

    /**
     * 执行上面123
     * 获取小说章节列表及链接-全章
     *
     * @param novelPath 小说链接
     * @return
     */
    public static List<ChapterList> getNovelChapterList(String novelPath) {
//        String url = urlSplice(search);
//        List<String> html = getNovelHtml(url);
//        String novelPath = getNovelPath2Html(html, search);
        List<String> chapterListUrl = getNovelHtml(novelPath);
        return getChapterList2Html(chapterListUrl, novelPath);
    }

    public static void main(String[] args) {
    }

}


















